package com.starinside.wp.utils;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class RedisUtil {


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JedisPool jedisPool;

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 释放jedis资源
     *
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * 获取redis键值-jsonObject
     *
     * @param key
     * @return
     */
    public Object getJsonObject(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String value = jedis.get(key);
            System.out.println("Getting key: " + key + " value: " + value);
            if (!StringUtils.isEmpty(value)) {
                if (value.startsWith("[")) {
                    return objectMapper.readValue(value, new TypeReference<List<Map<String, Object>>>() {
                    });
                } else if (value.startsWith("{")) {
                    return objectMapper.readValue(value, new TypeReference<Map<String, Object>>() {
                    });
                }
            }
        } catch (Exception e) {
            logger.error("getObject获取redis键值异常:key=" + key + " cause:" + e.getMessage());
        } finally {
            jedis.close();
        }
        return null;
    }

    /**
     * 设置redis键值-object
     *
     * @param key
     * @param value
     * @return
     */
    public String setJsonObject(String key, Object value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.set(key, objectMapper.writeValueAsString(value));
        } catch (Exception e) {
            logger.error("setObject设置redis键值异常:key=" + key + " value=" + value + " cause:" + e.getMessage());
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    /**
     * 设置redis键值-jsonObject
     *
     * @param key
     * @param value
     * @param expiretime
     * @return
     */
    public String setJsonObject(String key, Object value, int expiretime) {
        String result = "";
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String jsonValue = objectMapper.writeValueAsString(value);
            System.out.println("Setting key: " + key + " value: " + jsonValue);
            result = jedis.set(key, objectMapper.writeValueAsString(value));

            if (result.equals("OK")) {
                jedis.expire(key, expiretime);
            }
            return result;
        } catch (Exception e) {
            logger.error("setObject设置redis键值异常:key=" + key + " value=" + value + " cause:" + e.getMessage());
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return result;
    }

    /**
     * 删除key
     */
    public Long delkeyObject(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.del(key.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    public Boolean existsObject(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.exists(key.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    private Jedis getResource() {
        return jedisPool.getResource();
    }

    public boolean expire(String key, long time) {
        try (Jedis jedis = getResource()) {
            if (time > 0) {
                jedis.expire(key, (int) time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public long getExpire(String key) {
        try (Jedis jedis = getResource()) {
            return jedis.ttl(key);
        }
    }

    public boolean hasKey(String key) {
        try (Jedis jedis = getResource()) {
            return jedis.exists(key);
        }
    }

    public void del(String... keys) {
        try (Jedis jedis = getResource()) {
            jedis.del(keys);
        }
    }

    public Object get(String key) {
        try (Jedis jedis = getResource()) {
            return jedis.get(key);
        }
    }

    public boolean set(String key, Object value) {
        try (Jedis jedis = getResource()) {
            jedis.set(key, value.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean set(String key, Object value, long time) {
        try (Jedis jedis = getResource()) {
            if (time > 0) {
                jedis.setex(key, (int) time, value.toString());
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}

